/// @tags: SAM
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

namespace BlueQuantum {

int const N = 2e5 + 5e4 + 5;

int n, lst, tot;
int val[N << 1], ans[N];
char s[N];

struct Node {
  int ch[26], link, len;
} sam[N << 1];

inline void insert(int c) {
  int cur = ++tot, pos = lst;
  val[cur] = 1;
  sam[cur].len = sam[lst].len + 1;
  lst = cur;
  while (pos != -1 && !sam[pos].ch[c]) sam[pos].ch[c] = cur, pos = sam[pos].link;
  if (pos == -1) return;
  int q = sam[pos].ch[c];
  if (sam[pos].len + 1 == sam[q].len) return sam[cur].link = q, void();
  int clone = ++tot;
  sam[clone] = sam[q];
  sam[clone].len = sam[pos].len + 1;
  sam[cur].link = sam[q].link = clone;
  while (pos != -1 && sam[pos].ch[c] == q) sam[pos].ch[c] = clone, pos = sam[pos].link;
}

struct Edge {
  int v, nxt;
} e[N << 1];

int e_cnt, heads[N << 1];

inline void add(int u, int v) {
  e[++e_cnt].v = v, e[e_cnt].nxt = heads[u], heads[u] = e_cnt;
}

void dfs(int u) {
  for (int i = heads[u]; i; i = e[i].nxt) {
    dfs(e[i].v);
    val[u] += val[e[i].v];
  }
  ans[sam[u].len] = max(ans[sam[u].len], val[u]);
}

inline int main() {
  cin >> s;
  n = strlen(s);
  sam[0].link = -1;
  for (int i = 0; i < n; ++i) insert(s[i] - 'a');
  for (int i = 1; i <= tot; ++i) add(sam[i].link, i);
  dfs(0);
  for (int i = n - 1; i > 0; --i) ans[i] = max(ans[i + 1], ans[i]);
  for (int i = 1; i <= n; ++i) cout << ans[i] << '\n';
  return 0;
}

}  // namespace BlueQuantum

int main() {
#ifndef ONLINE_JUDGE
#ifdef LOCAL
  freopen("/tmp/CodeTmp/testdata.in", "r", stdin);
  freopen("/tmp/CodeTmp/testdata.out", "w", stdout);
#else
  freopen("SP8222 NSUBSTR-Substrings.in", "r", stdin);
  freopen("SP8222 NSUBSTR-Substrings.out", "w", stdout);
#endif
#endif

  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  return BlueQuantum::main();
}
